<div id="front-blurp">

    <h1>Duktape</h1>

    <p>Duktape 是一个轻量级的<b>嵌入式 JavaScript</b> 引擎, 专注于<b>可移植性</b>和<b>低占用率</b>。</p>

    <p>Duktape 可以被轻松地集成进一个 C/C++ 项目中: 只需要将 <code>duktape.c</code>、<code>duktape.h</code>
        和 <code>duk_config.h</code> 三个文件加入你的构建项目中，并使用
        Duktape API 来实现 C 代码与 ECMAScript 函数的双向调用。</p>

    <script>
        // <![CDATA[
        +function duktapeTest() {
            var _isDuktape = false;
            try {
                noSuchVariable.foo = 123;
            } catch (e) {
                if (typeof e.stack === 'string' && (e.stack.indexOf('duk_js_var') >= 0 || e.stack.indexOf('dukky') >= 0)) {
                    _isDuktape = true;
                }
            }
            try {
                var _isNetSurf = (typeof navigator === 'object' &&
                typeof navigator.userAgent === 'string' &&
                navigator.userAgent.indexOf('NetSurf') >= 0);
                if (_isNetSurf && _isDuktape) {
                    document.write('<p><b>Congratulations, you\'re using Duktape on NetSurf!</b></p>');
                }
            } catch (e) {
                //alert(e);
            }
        }();
        // ]]>
    </script>

    <h1>主要特性</h1>
    <ul>
        <li>可嵌入、可移植、低占用: 能够运行在 256kB 闪存（Flash）和 64kB 系统内存（RAM）的平台上；</li>
        <li>兼容 <a href="http://www.ecma-international.org/ecma-262/5.1/">Ecmascript E5/E5.1</a> 标准, 并借鉴了
            <a href="http://www.ecma-international.org/ecma-262/6.0/index.html">Ecmascript E6</a> 的部分特性；
        </li>
        <li>支持 Khronos/ES6 的 <a href="https://www.khronos.org/registry/typedarray/specs/latest/">TypedArray</a>
            对象和 Node.js 的 <a href="https://nodejs.org/docs/v0.12.1/api/buffer.html">Buffer</a> 对象；
        </li>
        <li>内置调试器；</li>
        <li>内置正则表达式引擎；</li>
        <li>内置 Unicode 支持；</li>
        <li>最小限度的平台依赖；</li>
        <li>整合了引用计数机制和 mark-and-sweep 垃圾回收机制；</li>
        <li>协同程序(coroutines)；</li>
        <li>属性（property）虚拟化中使用了 ECMAScript E6 Proxy 对象的一个子集；</li>
        <li>以字节码转储（dump）/ 加载的方式，来对已编译函数进行缓存；</li>
        <li>可发布版本中包含一个可选的日志框架，是基于 CommonJS 的模块加载来实现的，等等；</li>
        <li>采用 MIT 自由许可协议。</li>
    </ul>

    <h1>代码和内存占用</h1>
    <table>
        <tr>
            <td>&nbsp;</td>
            <td>x86 默认</td>
            <td>x86 低端内存</td>
            <td>x86 全低端内存</td>
        </tr>
        <tr>
            <td>代码</td>
            <td>170kB</td>
            <td>150kB</td>
            <td>200kB</td>
        </tr>
        <tr>
            <td>启动内存</td>
            <td>68kB</td>
            <td>35kB</td>
            <td>4kB</td>
        </tr>
    </table>

    <p>请参考 <a href="https://github.com/svaarala/duktape/blob/master/doc/low-memory.rst#optimizing-code-footprint">GCC
        选项</a>
        中的最小化代码占用。全 <a href="https://github.com/svaarala/duktape/blob/master/doc/low-memory.rst">低端内存</a>
        选项使用了“指针压缩”和基于 ROM 的字符串 / 对象。基于 ROM 的字符串 / 对象也可以用于其他非低端内存选项。</p>

    <h1>当前状态</h1>
    <ul>
        <li>稳定</li>
    </ul>

    <h1>技术支持</h1>
    <ul>
        <li>Duktape Wiki: <a href="http://wiki.duktape.org">wiki.duktape.org</a></li>
        <li>用户问答社区: Stack Overflow 上的 <a href="http://stackoverflow.com/questions/tagged/duktape">duktape</a> 标签</li>
        <li>Bugs 和功能需求: <a href="https://github.com/svaarala/duktape/issues">GitHub issues</a></li>
        <li>综合讨论区: <code>chat.freenode.net</code> 上的 IRC 频道 <code>#duktape</code>(<a
                href="https://webchat.freenode.net/">webchat</a>)
        </li>
    </ul>

    <h1>使用 Duktape 的项目</h1>

    <p>参见: <a href="http://wiki.duktape.org/ProjectsUsingDuktape.html">使用 Duktape 的项目</a>。</p>

    <p>如果你在自己的项目中使用了 Duktape，可以发送一封邮件或者开一个 GitHub issue 来将项目加到列表中。</p>

    <h1>类似的引擎</h1>

    <p>有多个与 Duktape 定位类似的 JavaScript 引擎，至少有如下几个: </p>
    <ul>
        <li><a href="https://github.com/espruino/Espruino">Espruino</a> (MPL v2.0)</li>
        <li><a href="http://samsung.github.io/jerryscript/">JerryScript</a> (Apache License v2.0)</li>
        <li><a href="http://mujs.com/">MuJS</a> (Affero GPL)</li>
        <li><a href="https://code.google.com/p/quad-wheel/">quad-wheel</a> (MIT License)</li>
        <li><a href="https://github.com/gfwilliams/tiny-js">tiny-js</a> (MIT license)</li>
        <li><a href="https://github.com/cesanta/v7">v7</a> (GPL v2.0)</li>
    </ul>

    <p>也可以参考 <a href="https://en.wikipedia.org/wiki/List_of_ECMAScript_engines">ECMAScript 引擎列表</a>。</p>

</div>  <!-- front-blurp -->

<div id="front-steps">

    <h1><span class="step">1</span> 参与构建</h1>

    <p>(可以通过查看 <a href="guide.html#gettingstarted">入门指南</a> 来了解更详细的介绍)</p>

    <p>Duktape 的 C 语言源文件和头文件可用于任何构建系统，只需将它们加入到你的项目中参与构建即可。
        可发行版本中包含一个 Makefile 示例以供参考。以下是个最简单的例子: </p>

<pre>
$ gcc -std=c99 -o test test.c duktape.c -lm
$ ./test
1+2=3
</pre>

    <h1><span class="step">2</span> 初始化一个环境（context）</h1>

    <p>在你程序的任何地方初始化并使用 Duktape:</p>

<pre class="c-code">
/* test.c */
#include &lt;stdio.h&gt;
#include &quot;duktape.h&quot;

int main(int argc, char *argv[]) {
  duk_context *ctx = duk_create_heap_default();
  duk_eval_string(ctx, "1+2");
  printf("1+2=%d\n", (int) duk_get_int(ctx, -1));
  duk_destroy_heap(ctx);
  return 0;
}
</pre>

    <h1><span class="step">3</span> 添加 C 函数绑定</h1>

    <p>想由 ECMAScript 代码来调用一个 C 函数，首先需要定义你的 C 函数: </p>

<pre class="c-code">
/* 作为一个嵌入式引擎, Duktape 默认没有提供 I/O 绑定.
 * 这是个简单的 print() 函数, 带有一个参数.
 */
static duk_ret_t native_print(duk_context *ctx) {
  printf("%s\n", duk_to_string(ctx, 0));
  return 0;  /* 没有返回值 (= undefined) */
}

/* 加法器: 将几个参数值相加. */
static duk_ret_t native_adder(duk_context *ctx) {
  int i;
  int n = duk_get_top(ctx);  /* 参数个数 */
  double res = 0.0;

  for (i = 0; i &lt; n; i++) {
    res += duk_to_number(ctx, i);
  }

  duk_push_number(ctx, res);
  return 1;  /* 一个返回值 */
}
</pre>

    <p>接下来，注册你这个函数，比例将它注册到全局对象中: </p>

<pre class="c-code">
duk_push_c_function(ctx, native_print, 1 /*nargs*/);
duk_put_global_string(ctx, "print");
duk_push_c_function(ctx, native_adder, DUK_VARARGS);
duk_put_global_string(ctx, "adder");
</pre>

    <p>然后，你就可以在 ECMAScript 代码中调用你的函数了:</p>

<pre class="c-code">
duk_eval_string_noresult(ctx, "print('2+3=' + adder(2, 3));");
</pre>

</div>  <!-- front-steps -->

